﻿namespace LastfmNet.Api
{
    using System;
    using System.Globalization;
    using LastfmNet.Models;

    /// <summary>
    /// Last.fm API chart methods
    /// </summary>
    public class ChartApi
    {
        /// <summary>
        /// Reference to the Lastfm host class
        /// </summary>
        private Lastfm lastfmApi;

        /// <summary>
        /// Initializes a new instance of the ChartApi class.
        /// </summary>
        /// <param name="lastfmApi">Reference to the Lastfm host class</param>
        internal ChartApi(Lastfm lastfmApi)
        {
            this.lastfmApi = lastfmApi;
        }

        /// <summary>
        /// Get the hyped artists chart
        /// This service does not require authentication. 
        /// </summary>
        /// <param name="page">The page number to fetch. Defaults to first page.</param>
        /// <param name="limit">The number of results to fetch per page. Defaults to 50.</param>
        /// <returns>Hyped artists chart</returns>
        public LastfmNet.Models.LastfmPager<HypedArtist> GetHypedArtists(int page = 1, int limit = 50)
        {
            LastfmParameters parameters = new LastfmParameters("chart.getHypedArtists");
            parameters["page"] = page.ToString(CultureInfo.InvariantCulture);
            parameters["limit"] = limit.ToString(CultureInfo.InvariantCulture);
            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters);
                return new LastfmNet.Models.LastfmPager<HypedArtist>(result.MainNode);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to get hyped artists! (" + ex.Message + ")", ex);
            }
        }

        /// <summary>
        /// Get the top tracks chart
        /// This service does not require authentication. 
        /// </summary>
        /// <param name="page">The page number to fetch. Defaults to first page.</param>
        /// <param name="limit">The number of results to fetch per page. Defaults to 50.</param>
        /// <returns>Top tracks chart</returns>
        public LastfmNet.Models.LastfmPager<HypedTrack> GetHypedTracks(int page = 1, int limit = 50)
        {
            LastfmParameters parameters = new LastfmParameters("chart.getHypedTracks");
            parameters["page"] = page.ToString(CultureInfo.InvariantCulture);
            parameters["limit"] = limit.ToString(CultureInfo.InvariantCulture);
            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters);
                return new LastfmNet.Models.LastfmPager<HypedTrack>(result.MainNode);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to get hyped tracks! (" + ex.Message + ")", ex);
            }
        }

        /// <summary>
        /// Get the most loved tracks chart
        /// This service does not require authentication. 
        /// </summary>
        /// <param name="page">The page number to fetch. Defaults to first page.</param>
        /// <param name="limit">The number of results to fetch per page. Defaults to 50.</param>
        /// <returns>The most loved tracks chart</returns>
        public LastfmNet.Models.LastfmPager<LovedTrack> GetLovedTracks(int page = 1, int limit = 50)
        {
            LastfmParameters parameters = new LastfmParameters("chart.getLovedTracks");
            parameters["page"] = page.ToString(CultureInfo.InvariantCulture);
            parameters["limit"] = limit.ToString(CultureInfo.InvariantCulture);
            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters);
                return new LastfmNet.Models.LastfmPager<LovedTrack>(result.MainNode);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to get loved tracks! (" + ex.Message + ")", ex);
            }
        }

        /// <summary>
        /// Get the top artists chart
        /// This service does not require authentication. 
        /// </summary>
        /// <param name="page">The page number to fetch. Defaults to first page.</param>
        /// <param name="limit">The number of results to fetch per page. Defaults to 50.</param>
        /// <returns>Top artists chart</returns>
        public LastfmNet.Models.LastfmPager<TopArtist> GetTopArtists(int page = 1, int limit = 50)
        {
            LastfmParameters parameters = new LastfmParameters("chart.getTopArtists");
            parameters["page"] = page.ToString(CultureInfo.InvariantCulture);
            parameters["limit"] = limit.ToString(CultureInfo.InvariantCulture);
            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters);
                return new LastfmNet.Models.LastfmPager<TopArtist>(result.MainNode);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to get top artists! (" + ex.Message + ")", ex);
            }
        }

        /// <summary>
        /// Get the top tags chart
        /// This service does not require authentication. 
        /// </summary>
        /// <param name="page">The page number to fetch. Defaults to first page.</param>
        /// <param name="limit">The number of results to fetch per page. Defaults to 50.</param>
        /// <returns>Top tags chart</returns>
        public LastfmNet.Models.LastfmPager<LastfmNet.Models.Tag> GetTopTags(int page = 1, int limit = 50)
        {
            LastfmParameters parameters = new LastfmParameters("chart.getTopTags");
            parameters["page"] = page.ToString(CultureInfo.InvariantCulture);
            parameters["limit"] = limit.ToString(CultureInfo.InvariantCulture);
            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters);
                return new LastfmNet.Models.LastfmPager<LastfmNet.Models.Tag>(result.MainNode);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to get top tags! (" + ex.Message + ")", ex);
            }
        }

        /// <summary>
        /// Get the top tracks chart
        /// This service does not require authentication. 
        /// </summary>
        /// <param name="page">The page number to fetch. Defaults to first page.</param>
        /// <param name="limit">The number of results to fetch per page. Defaults to 50.</param>
        /// <returns>The top tracks chart</returns>
        public LastfmNet.Models.LastfmPager<TopTrack> GetTopTracks(int page = 1, int limit = 50)
        {
            LastfmParameters parameters = new LastfmParameters("chart.getTopTracks");
            parameters["page"] = page.ToString(CultureInfo.InvariantCulture);
            parameters["limit"] = limit.ToString(CultureInfo.InvariantCulture);
            parameters.AddApiKey(this.lastfmApi.Session.ApiKey);
            try
            {
                LastfmResponse result = this.lastfmApi.MakeRequest(parameters);
                return new LastfmNet.Models.LastfmPager<TopTrack>(result.MainNode);
            }
            catch (Exception ex)
            {
                throw new LastfmNetException("Unable to get top tracks! (" + ex.Message + ")", ex);
            }
        }
    }
}
